export default function(coder: any) {


  coder['procedures_defreturn'] = function(block: any) {
    // Define a procedure with a return value.
    var funcName = coder.variableDB_.getName(
        block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
    var branch = coder.statementToCode(block, 'STACK');
    if (coder.STATEMENT_PREFIX) {
      var id = block.id.replace(/\$/g, '$$$$');  // Issue 251.
      branch = coder.prefixLines(
          coder.STATEMENT_PREFIX.replace(/%1/g,
          '\'' + id + '\''), coder.INDENT) + branch;
    }
    if (coder.INFINITE_LOOP_TRAP) {
      branch = coder.INFINITE_LOOP_TRAP.replace(/%1/g,
          '\'' + block.id + '\'') + branch;
    }
    var returnValue = coder.valueToCode(block, 'RETURN',
        coder.ORDER_NONE) || '';
    if (returnValue) {
      returnValue = coder.INDENT + 'return ' + returnValue + ';\n';
    }
    var args = [];
    for (var i = 0; i < block.arguments_.length; i++) {
      args[i] = coder.variableDB_.getName(block.arguments_[i],
          Blockly.Variables.NAME_TYPE);
    }
    var code = 'function ' + funcName + '(' + args.join(', ') + ') {\n' +
        branch + returnValue + '}';
    code = coder.scrub_(block, code);
    // Add % so as not to collide with helper functions in definitions list.
    coder.definitions_['%' + funcName] = code;
    return null;
  };

  // Defining a procedure without a return value uses the same generator as
  // a procedure with a return value.
  coder['procedures_defnoreturn'] =
      coder['procedures_defreturn'];

  coder['procedures_callreturn'] = function(block: any) {
    // Call a procedure with a return value.
    var funcName = coder.variableDB_.getName(
        block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
    var args = [];
    for (var i = 0; i < block.arguments_.length; i++) {
      args[i] = coder.valueToCode(block, 'ARG' + i,
          coder.ORDER_COMMA) || 'null';
    }
    var code = funcName + '(' + args.join(', ') + ')';
    return [code, coder.ORDER_FUNCTION_CALL];
  };

  coder['procedures_callnoreturn'] = function(block: any) {
    // Call a procedure with no return value.
    var funcName = coder.variableDB_.getName(
        block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
    var args = [];
    for (var i = 0; i < block.arguments_.length; i++) {
      args[i] = coder.valueToCode(block, 'ARG' + i,
          coder.ORDER_COMMA) || 'null';
    }
    var code = funcName + '(' + args.join(', ') + ');\n';
    return code;
  };

  coder['procedures_ifreturn'] = function(block: any) {
    // Conditionally return value from a procedure.
    var condition = coder.valueToCode(block, 'CONDITION',
        coder.ORDER_NONE) || 'false';
    var code = 'if (' + condition + ') {\n';
    if (block.hasReturnValue_) {
      var value = coder.valueToCode(block, 'VALUE',
          coder.ORDER_NONE) || 'null';
      code += coder.INDENT + 'return ' + value + ';\n';
    } else {
      code += coder.INDENT + 'return;\n';
    }
    code += '}\n';
    return code;
  };

}